home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / athena / moira / patch2 < prev    next >
Encoding:
Text File  |  1990-09-04  |  54.7 KB  |  1,705 lines

  1. This is patch #2 to Moira release 2.2, of Wed May  2 12:11:40 EDT 1990
  2. (revised Wed Sep  5 16:31:30 EDT 1990)
  3.  
  4. BE SURE TO APPLY THIS PATCH WITH
  5.  
  6.    patch -p
  7.  
  8. TO PRESERVE THE DIRECTORY HIERARCHY.
  9.  
  10. The following bugs are fixed:
  11.  
  12. 1. Update patchlevel.h to indicate we are at patchlevel 2.
  13. 2. Fix a list dependancy problem and some lint errors in the aliases extract.
  14. 3. Have top-level Makefile create the profiled directories.
  15. 4. Speedups and several fixes to the mailhub extract.
  16. 5. Have the install_dirs script no longer use sms_untar (no longer
  17.    works around old quota bugs).
  18. 6. Several pieces of documentation refer to the file db/dbbuild which
  19.    was renamed to db/newdb a long time ago.
  20. 7. The installation instructions didn't mention nightly backups.
  21. 8. Some incorrect array sizes in the moira client could cause coredumps.
  22. 9. Some lint in the moira client could cause unusual behavior under
  23.    certain compilers.
  24. 10.Removed cistrcmp() which duplicated library function strcasecmp().
  25.  
  26.  
  27.  
  28. *** /tmp/,RCSt1023961    Wed May  2 12:14:25 1990
  29. --- patchlevel.h    Wed May  2 12:07:36 1990
  30. ***************
  31. *** 1 ****
  32. ! #define PATCHLEVEL 1
  33. --- 1 ----
  34. ! #define PATCHLEVEL 2
  35. *** /tmp/,RCSt1023970    Wed May  2 12:15:15 1990
  36. --- gen/aliases.qc    Tue Apr 10 12:42:38 1990
  37. ***************
  38. *** 1,4 ****
  39. ! /* $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/aliases.qc,v 1.14 90/03/19 19:05:48 mar Exp $
  40.    *
  41.    * This generates the /usr/lib/aliases mail aliases file for the mailhub.
  42.    * The aliases file will contain:
  43. --- 1,4 ----
  44. ! /* $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/aliases.qc,v 1.15 90/04/10 12:42:07 mar Exp $
  45.    *
  46.    * This generates the /usr/lib/aliases mail aliases file for the mailhub.
  47.    * The aliases file will contain:
  48. ***************
  49. *** 110,116 ****
  50.   static int ingerr(num)
  51.       int *num;
  52.   {
  53. -     char buf[256];
  54.       int ingres_errno;
  55.   
  56.       switch (*num) {
  57. --- 110,115 ----
  58. ***************
  59. *** 270,276 ****
  60.       return;
  61.       }
  62.       l->maillist = 2;
  63. !     output_mlist(id, l, out);
  64.   
  65.       if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
  66.         save_mlist(0, l1, 1);
  67. --- 269,275 ----
  68.       return;
  69.       }
  70.       l->maillist = 2;
  71. !     output_mlist(id, l);
  72.   
  73.       if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
  74.         save_mlist(0, l1, 1);
  75. ***************
  76. *** 277,283 ****
  77.       
  78.       for (m = l->m; m; m = m->next) {
  79.       if (m->list_id && (l1 = (struct list *)hash_lookup(lists, m->list_id)))
  80. !       save_mlist(0, l1, 0);
  81.       }
  82.   }
  83.   
  84. --- 276,282 ----
  85.       
  86.       for (m = l->m; m; m = m->next) {
  87.       if (m->list_id && (l1 = (struct list *)hash_lookup(lists, m->list_id)))
  88. !       save_mlist(0, l1, 1);
  89.       }
  90.   }
  91.   
  92. ***************
  93. *** 284,298 ****
  94.   
  95.   int lwid, bol, awid;
  96.   
  97. ! output_mlist(id, l, dummy)
  98.   int id;
  99.   register struct list *l;
  100. - int dummy;
  101.   {
  102.       struct list *l1;
  103.       register struct member *m;
  104.       struct user *u;
  105. -     int id;
  106.   
  107.       put_fill(out, l->description);
  108.       if (l->acl_t ==  'L') {
  109. --- 283,295 ----
  110.   
  111.   int lwid, bol, awid;
  112.   
  113. ! output_mlist(id, l)
  114.   int id;
  115.   register struct list *l;
  116.   {
  117.       struct list *l1;
  118.       register struct member *m;
  119.       struct user *u;
  120.   
  121.       put_fill(out, l->description);
  122.       if (l->acl_t ==  'L') {
  123. ***************
  124. *** 380,388 ****
  125.   do_poboxes(out)
  126.   FILE *out;
  127.   {
  128. -     register char *p;
  129. -     char *index();
  130.       fprintf(out, "\n%s\n# User Poboxes\n%s\n", divide, divide);
  131.   
  132.       hash_step(users, do_pobox, out);
  133. --- 377,382 ----
  134. *** /tmp/,RCSt1023986    Wed May  2 12:20:15 1990
  135. --- Makefile    Wed May  2 12:19:58 1990
  136. ***************
  137. *** 1,7 ****
  138.   # Makefile for SMS 2.0
  139.   #
  140.   #    $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/RCS/Makefile,v $
  141. ! #    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/RCS/Makefile,v 1.14 90/03/30 17:30:21 mar Exp $
  142.   #    $Author: mar $
  143.   #
  144.   # (c) Copyright 1988 by the Massachusetts Institute of Technology.
  145. --- 1,7 ----
  146.   # Makefile for SMS 2.0
  147.   #
  148.   #    $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/RCS/Makefile,v $
  149. ! #    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/RCS/Makefile,v 1.15 90/05/02 12:19:43 mar Exp $
  150.   #    $Author: mar $
  151.   #
  152.   # (c) Copyright 1988 by the Massachusetts Institute of Technology.
  153. ***************
  154. *** 16,21 ****
  155. --- 16,22 ----
  156.   INSTALLDIRS= include
  157.   
  158.   all:
  159. +     -@mkdir et/profiled gdb/profiled rpc/profiled server/profiled
  160.       if [ -f /usr/rtingres/bin/eqc ]; then \
  161.           DIRS="${ALLDIRS}" ; \
  162.       else \
  163. *** /tmp/,RCSt1023997    Wed May  2 12:25:33 1990
  164. --- gen/mailhub.qc    Fri Apr 13 15:16:25 1990
  165. ***************
  166. *** 1,5 ****
  167.   
  168. ! /* $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/mailhub.qc,v 1.5 90/03/19 19:06:11 mar Exp $
  169.    *
  170.    * This generates the /usr/lib/aliases file for the mailhub.
  171.    *
  172. --- 1,5 ----
  173.   
  174. ! /* $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/mailhub.qc,v 1.7 90/04/13 15:15:28 mar Exp $
  175.    *
  176.    * This generates the /usr/lib/aliases file for the mailhub.
  177.    *
  178. ***************
  179. *** 23,28 ****
  180. --- 23,29 ----
  181.   char *whoami = "mailhub.gen";
  182.   char *ingres_date_and_time();
  183.   char *perm_malloc();
  184. + char *pstrsave();
  185.   char *divide = "##############################################################";
  186.   
  187.   #define ML_WID    72
  188. ***************
  189. *** 31,43 ****
  190.   #define FALSE 0
  191.   #define TRUE (!FALSE)
  192.   
  193.   
  194.   main(argc, argv)
  195.   int argc;
  196.   char **argv;
  197.   {
  198.       long tm = time(NULL);
  199. -     FILE *out= stdout;
  200.       char filename[64], *targetfile;
  201.       struct stat sb;
  202.   ##  int flag;
  203. --- 32,45 ----
  204.   #define FALSE 0
  205.   #define TRUE (!FALSE)
  206.   
  207. + FILE *out= stdout;
  208.   
  209.   main(argc, argv)
  210.   int argc;
  211.   char **argv;
  212.   {
  213.       long tm = time(NULL);
  214.       char filename[64], *targetfile;
  215.       struct stat sb;
  216.   ##  int flag;
  217. ***************
  218. *** 82,89 ****
  219.       sort_info();
  220.   
  221.       fprintf(stderr, "Dumping information\n");
  222. !     do_lists(out);
  223. !     do_people(out);
  224.   
  225.       fprintf(out, "\n%s\n# End of aliases file\n", divide);
  226.   
  227. --- 84,90 ----
  228.       sort_info();
  229.   
  230.       fprintf(stderr, "Dumping information\n");
  231. !     do_people();
  232.   
  233.       fprintf(out, "\n%s\n# End of aliases file\n", divide);
  234.   
  235. ***************
  236. *** 165,180 ****
  237.   ##  retrieve (buf = list.modtime) where list.list_id = 0
  238.   
  239.       cnt = 0;
  240. !     machines = create_hash(1000);
  241. ! ##  retrieve (id = machine.mach_id, name = machine.#name) {
  242.         if (s = index(name, '.'))
  243.       *s = 0;
  244.   #ifdef ATHENA
  245. !       sprintf(buf, "%s.LOCAL", name);
  246. !       if (hash_store(machines, id, strsave(buf)) < 0) {
  247. ! #else
  248. !       if (hash_store(machines, id, strsave(name)) < 0) {
  249.   #endif
  250.         fprintf(stderr, "Out of memory!\n");
  251.         exit(MR_NO_MEM);
  252.         }
  253. --- 166,182 ----
  254.   ##  retrieve (buf = list.modtime) where list.list_id = 0
  255.   
  256.       cnt = 0;
  257. !     machines = create_hash(10);
  258. ! ##  retrieve (id = machine.mach_id, name = machine.#name)
  259. ! ##        where machine.mach_id = users.pop_id {
  260.         if (s = index(name, '.'))
  261.       *s = 0;
  262. +       else
  263. +     strtrim(name);
  264.   #ifdef ATHENA
  265. !       strcat(name, ".LOCAL");
  266.   #endif
  267. +       if (hash_store(machines, id, pstrsave(name)) < 0) {
  268.         fprintf(stderr, "Out of memory!\n");
  269.         exit(MR_NO_MEM);
  270.         }
  271. ***************
  272. *** 183,191 ****
  273.       fprintf(stderr, "Loaded %d machines\n", cnt);
  274.   
  275.       cnt = 0;
  276. !     strings = create_hash(2000);
  277.   ##  retrieve (id = strings.string_id, name = strings.string) {
  278. !     if (hash_store(strings, id, strsave(strtrim(name))) < 0) {
  279.           fprintf(stderr, "Out of memory!\n");
  280.           exit(MR_NO_MEM);
  281.       }
  282. --- 185,193 ----
  283.       fprintf(stderr, "Loaded %d machines\n", cnt);
  284.   
  285.       cnt = 0;
  286. !     strings = create_hash(4000);
  287.   ##  retrieve (id = strings.string_id, name = strings.string) {
  288. !     if (hash_store(strings, id, pstrsave(strtrim(name))) < 0) {
  289.           fprintf(stderr, "Out of memory!\n");
  290.           exit(MR_NO_MEM);
  291.       }
  292. ***************
  293. *** 201,209 ****
  294.   ##          type = u.potype, pid = u.pop_id, bid = u.box_id) 
  295.   ##    where u.status != 3 {
  296.       u = (struct user *) perm_malloc(sizeof(struct user));
  297. !     u->login = strsave(strtrim(name));
  298. !     u->first = strsave(strtrim(fname));
  299. !     u->last  = strsave(strtrim(lname));
  300.       if (mname[0] != ' ')
  301.         u->mi = mname[0];
  302.       else
  303. --- 203,211 ----
  304.   ##          type = u.potype, pid = u.pop_id, bid = u.box_id) 
  305.   ##    where u.status != 3 {
  306.       u = (struct user *) perm_malloc(sizeof(struct user));
  307. !     u->login = pstrsave(strtrim(name));
  308. !     u->first = pstrsave(strtrim(fname));
  309. !     u->last  = pstrsave(strtrim(lname));
  310.       if (mname[0] != ' ')
  311.         u->mi = mname[0];
  312.       else
  313. ***************
  314. *** 210,217 ****
  315.         u->mi = 0;
  316.   
  317.       if (type[0] == 'P' && (s = hash_lookup(machines, pid))) {
  318. !         sprintf(buf, "%s@%s", strtrim(name), s);
  319. !         u->pobox = strsave(buf);
  320.       } else if (type[0] ==  'S') {
  321.           u->pobox = hash_lookup(strings, bid);
  322.       } else
  323. --- 212,219 ----
  324.         u->mi = 0;
  325.   
  326.       if (type[0] == 'P' && (s = hash_lookup(machines, pid))) {
  327. !         sprintf(buf, "%s@%s", u->login, s);
  328. !         u->pobox = pstrsave(buf);
  329.       } else if (type[0] ==  'S') {
  330.           u->pobox = hash_lookup(strings, bid);
  331.       } else
  332. ***************
  333. *** 231,237 ****
  334.   ##          type = l.acl_type, acl = l.acl_id)
  335.   ##    where l.active != 0 {
  336.       l = (struct list *) perm_malloc(sizeof(struct list));
  337. !     l->name = strsave(strtrim(name));
  338.       l->maillist = maillistp;
  339.       l->acl_t = type[0];
  340.       l->acl_id = acl;
  341. --- 233,239 ----
  342.   ##          type = l.acl_type, acl = l.acl_id)
  343.   ##    where l.active != 0 {
  344.       l = (struct list *) perm_malloc(sizeof(struct list));
  345. !     l->name = pstrsave(strtrim(name));
  346.       l->maillist = maillistp;
  347.       l->acl_t = type[0];
  348.       l->acl_id = acl;
  349. ***************
  350. *** 284,291 ****
  351.       register struct member *m;
  352.       register struct list *l1;
  353.   
  354. !     if (l->maillist == 2 ||
  355. !     l->maillist == 3 ||
  356.       (l->maillist == 0 && !force))
  357.         return;
  358.   
  359. --- 286,292 ----
  360.       register struct member *m;
  361.       register struct list *l1;
  362.   
  363. !     if (l->maillist > 1 ||
  364.       (l->maillist == 0 && !force))
  365.         return;
  366.   
  367. ***************
  368. *** 295,301 ****
  369.       return;
  370.       }
  371.       l->maillist = 2;
  372. !     insert_name(l->name, -id, TRUE, FALSE);
  373.   
  374.       if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
  375.         save_mlist(0, l1, TRUE);
  376. --- 296,303 ----
  377.       return;
  378.       }
  379.       l->maillist = 2;
  380. !     insert_name(l->name, -1, TRUE, FALSE);
  381. !     output_mlist(id, l);
  382.   
  383.       if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
  384.         save_mlist(0, l1, TRUE);
  385. ***************
  386. *** 356,366 ****
  387.           exit(MR_NO_MEM);
  388.       }
  389.       if (copy)
  390. !       ns->name = strsave(s);
  391.       else
  392.         ns->name = s;
  393.       ns->keep = nodups;
  394.       ns->id = id;
  395.       if (hash_store(names, code, ns) < 0) {
  396.           fprintf(stderr, "Out of memory!\n");
  397.           exit(MR_NO_MEM);
  398. --- 358,369 ----
  399.           exit(MR_NO_MEM);
  400.       }
  401.       if (copy)
  402. !       ns->name = pstrsave(s);
  403.       else
  404.         ns->name = s;
  405.       ns->keep = nodups;
  406.       ns->id = id;
  407. +     ns->next = NULL;
  408.       if (hash_store(names, code, ns) < 0) {
  409.           fprintf(stderr, "Out of memory!\n");
  410.           exit(MR_NO_MEM);
  411. ***************
  412. *** 380,395 ****
  413.       }
  414.       ns = ns->next;
  415.       if (copy)
  416. !       ns->name = strsave(s);
  417.       else
  418.         ns->name = s;
  419.       ns->keep = nodups;
  420.       ns->id = id;
  421.       return;
  422.       }
  423.    foundns:
  424. !     if (nodups || ns->keep)
  425. !       return;
  426.       ns->id = 0;
  427.   }
  428.   
  429. --- 383,402 ----
  430.       }
  431.       ns = ns->next;
  432.       if (copy)
  433. !       ns->name = pstrsave(s);
  434.       else
  435.         ns->name = s;
  436.       ns->keep = nodups;
  437.       ns->id = id;
  438. +     ns->next = NULL;
  439.       return;
  440.       }
  441.    foundns:
  442. !     if (nodups || ns->keep) {
  443. !     if (nodups && ns->keep)
  444. !       fprintf(stderr, "duplicated named: %s\n", s);
  445. !     return;
  446. !     }
  447.       ns->id = 0;
  448.   }
  449.   
  450. ***************
  451. *** 444,450 ****
  452. --- 451,460 ----
  453.   {
  454.       names = create_hash(20001);
  455.       hash_step(users, insert_login, NULL);
  456. +     incount = 0;
  457. +     fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
  458.       hash_step(lists, save_mlist, FALSE);
  459. +     fprintf(stderr, "Output %d lists\n", incount);
  460.       hash_step(users, insert_names, NULL);
  461.       fprintf(stderr, "Inserted %d names\n", incount);
  462.   }
  463. ***************
  464. *** 480,496 ****
  465.   
  466.   int lwid, bol, awid;
  467.   
  468. ! output_mlist(id, l, out)
  469.   int id;
  470.   register struct list *l;
  471. - FILE *out;
  472.   {
  473.       struct list *l1;
  474.       register struct member *m;
  475.       register struct user *u;
  476.   
  477. -     if (l->maillist != 2)
  478. -       return;
  479.       if (l->acl_t ==  'L' &&
  480.       (l1 = (struct list *) hash_lookup(lists, l->acl_id)))
  481.         fprintf(out, "owner-%s: %s\n%s: ", l->name, l1->name, l->name);
  482. --- 490,503 ----
  483.   
  484.   int lwid, bol, awid;
  485.   
  486. ! output_mlist(id, l)
  487.   int id;
  488.   register struct list *l;
  489.   {
  490.       struct list *l1;
  491.       register struct member *m;
  492.       register struct user *u;
  493.   
  494.       if (l->acl_t ==  'L' &&
  495.       (l1 = (struct list *) hash_lookup(lists, l->acl_id)))
  496.         fprintf(out, "owner-%s: %s\n%s: ", l->name, l1->name, l->name);
  497. ***************
  498. *** 497,502 ****
  499. --- 504,512 ----
  500.       else if (l->acl_t ==  'U' &&
  501.            (u = (struct user *) hash_lookup(users, l->acl_id)))
  502.         fprintf(out, "owner-%s: %s\n%s: ", l->name, u->login, l->name);
  503. +     else
  504. +       fprintf(out, "%s: ", l->name);
  505. +       
  506.   
  507.       lwid = strlen(l->name) + 2;
  508.       bol = 1;
  509. ***************
  510. *** 547,565 ****
  511.   }
  512.   
  513.   
  514. ! do_lists(out)
  515. ! FILE *out;
  516.   {
  517.       incount = 0;
  518. -     fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
  519. -     hash_step(lists, output_mlist, out);
  520. -     fprintf(stderr, "Output %d lists\n", incount);
  521. - }
  522. - do_people(out)
  523. - FILE *out;
  524. - {
  525. -     incount = 0;
  526.       fprintf(out, "\n%s\n# People\n%s\n", divide, divide);
  527.       hash_step(names, output_data, out);
  528.       fprintf(stderr, "Output %d entries\n", incount);
  529. --- 557,565 ----
  530.   }
  531.   
  532.   
  533. ! do_people()
  534.   {
  535.       incount = 0;
  536.       fprintf(out, "\n%s\n# People\n%s\n", divide, divide);
  537.       hash_step(names, output_data, out);
  538.       fprintf(stderr, "Output %d entries\n", incount);
  539. ***************
  540. *** 586,588 ****
  541. --- 586,765 ----
  542.       return(ret);
  543.   }
  544.   
  545. + /*
  546. +  * Make a (permenant) copy of a string.
  547. +  */
  548. + char *
  549. + pstrsave(s)
  550. +     char *s;
  551. + {
  552. +     register int len;
  553. +     register char *p;
  554. +     /* Kludge for sloppy string semantics */
  555. +     if (!s) {
  556. +         printf("NULL != \"\" !!!!\r\n");
  557. +         p = perm_malloc(1);
  558. +         *p = '\0';
  559. +         return p;
  560. +     }
  561. +     len = strlen(s) + 1;
  562. +     p = perm_malloc((u_int)len);
  563. +     if (p) bcopy(s, p, len);
  564. +     return p;
  565. + }
  566. + #define hash_func(h, key) (key >= 0 ? (key % h->size) : (-key % h->size))
  567. + /* Create a hash table.  The size is just a hint, not a maximum. */
  568. + struct hash *create_hash(size)
  569. + int size;
  570. + {
  571. +     struct hash *h;
  572. +     h = (struct hash *) perm_malloc(sizeof(struct hash));
  573. +     if (h == (struct hash *) NULL)
  574. +       return((struct hash *) NULL);
  575. +     h->size = size;
  576. +     h->data = (struct bucket **) perm_malloc(size * sizeof(char *));
  577. +     if (h->data == (struct bucket **) NULL) {
  578. +     free(h);
  579. +     return((struct hash *) NULL);
  580. +     }
  581. +     bzero(h->data, size * sizeof(char *));
  582. +     return(h);
  583. + }
  584. + /* Lookup an object in the hash table.  Returns the value associated with
  585. +  * the key, or NULL (thus NULL is not a very good value to store...)
  586. +  */
  587. + char *hash_lookup(h, key)
  588. + struct hash *h;
  589. + register int key;
  590. + {
  591. +     register struct bucket *b;
  592. +     b = h->data[hash_func(h, key)];
  593. +     while (b && b->key != key)
  594. +       b = b->next;
  595. +     if (b && b->key == key)
  596. +       return(b->data);
  597. +     else
  598. +       return(NULL);
  599. + }
  600. + /* Update an existing object in the hash table.  Returns 1 if the object
  601. +  * existed, or 0 if not.
  602. +  */
  603. + int hash_update(h, key, value)
  604. + struct hash *h;
  605. + register int key;
  606. + char *value;
  607. + {
  608. +     register struct bucket *b;
  609. +     b = h->data[hash_func(h, key)];
  610. +     while (b && b->key != key)
  611. +       b = b->next;
  612. +     if (b && b->key == key) {
  613. +     b->data = value;
  614. +     return(1);
  615. +     } else
  616. +       return(0);
  617. + }
  618. + /* Store an item in the hash table.  Returns 0 if the key was not previously
  619. +  * there, 1 if it was, or -1 if we ran out of memory.
  620. +  */
  621. + int hash_store(h, key, value)
  622. + struct hash *h;
  623. + register int key;
  624. + char *value;
  625. + {
  626. +     register struct bucket *b, **p;
  627. +     p = &(h->data[hash_func(h, key)]);
  628. +     if (*p == NULL) {
  629. +     b = *p = (struct bucket *) perm_malloc(sizeof(struct bucket));
  630. +     if (b == (struct bucket *) NULL)
  631. +       return(-1);
  632. +     b->next = NULL;
  633. +     b->key = key;
  634. +     b->data = value;
  635. +     return(0);
  636. +     }
  637. +     for (b = *p; b && b->key != key; b = *p)
  638. +       p = (struct bucket **) *p;
  639. +     if (b && b->key == key) {
  640. +     b->data = value;
  641. +     return(1);
  642. +     }
  643. +     b = *p = (struct bucket *) perm_malloc(sizeof(struct bucket));
  644. +     if (b == (struct bucket *) NULL)
  645. +       return(-1);
  646. +     b->next = NULL;
  647. +     b->key = key;
  648. +     b->data = value;
  649. +     return(0);
  650. + }
  651. + /* Search through the hash table for a given value.  For each piece of
  652. +  * data with that value, call the callback proc with the corresponding key.
  653. +  */
  654. + hash_search(h, value, callback)
  655. + struct hash *h;
  656. + register char *value;
  657. + void (*callback)();
  658. + {
  659. +     register struct bucket *b, **p;
  660. +     for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
  661. +     for (b = *p; b; b = b->next) {
  662. +         if (b->data == value)
  663. +           (*callback)(b->key);
  664. +     }
  665. +     }
  666. + }
  667. + /* Step through the hash table, calling the callback proc with each key.
  668. +  */
  669. + hash_step(h, callback, hint)
  670. + struct hash *h;
  671. + void (*callback)();
  672. + char *hint;
  673. + {
  674. +     register struct bucket *b, **p;
  675. +     for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
  676. +     for (b = *p; b; b = b->next) {
  677. +         (*callback)(b->key, b->data, hint);
  678. +     }
  679. +     }
  680. + }
  681. + /* Deallocate all of the memory associated with a table */
  682. + hash_destroy(h)
  683. + struct hash *h;
  684. + {
  685. +     register struct bucket *b, **p, *b1;
  686. +     for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
  687. +     for (b = *p; b; b = b1) {
  688. +         b1 = b->next;
  689. +         free(b);
  690. +     }
  691. +     }
  692. + }
  693. *** /tmp/,RCSt1024004    Wed May  2 12:29:06 1990
  694. --- gen/install_dirs    Tue Apr 10 17:06:20 1990
  695. ***************
  696. *** 56,64 ****
  697.            # *****
  698.   
  699.            # Give user prototype files
  700. !          # sms_untar is a setuid argv[1] tar xfp -
  701. !          (cd $tmpdir; sms_untar $uid < $USERTAR)
  702.            if ($status) set WARN
  703.            breaksw      
  704.         case COURSE:
  705.        /bin/chmod 775 $tmpdir
  706. --- 56,64 ----
  707.            # *****
  708.   
  709.            # Give user prototype files
  710. !          (cd $tmpdir; tar xf $USERTAR)
  711.            if ($status) set WARN
  712. +      chown $uid.$gid $tmpdir $tmpdir/.??* $tmpdir/*
  713.            breaksw      
  714.         case COURSE:
  715.        /bin/chmod 775 $tmpdir
  716. ***************
  717. *** 75,79 ****
  718.   
  719.   #
  720.   #     $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/install_dirs,v $
  721. ! #    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/install_dirs,v 1.8 90/03/19 19:06:05 mar Exp $
  722.   #
  723. --- 75,79 ----
  724.   
  725.   #
  726.   #     $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/install_dirs,v $
  727. ! #    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/gen/RCS/install_dirs,v 1.9 90/04/10 17:06:02 mar Exp $
  728.   #
  729. *** /mit/bitbucket/mar/moira/db/README    Wed Feb 14 11:12:49 1990
  730. --- db/README    Wed Apr 25 14:54:25 1990
  731. ***************
  732. *** 1,8 ****
  733. ! /mit/smsdev/db/README: $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/db/RCS/README,v 1.3 90/02/14 11:12:40 mar Exp $
  734.   
  735.   This directory contains stuff necessary to create and initialize an
  736.   sms database.  Note that some other directories rely on files here
  737. ! (notably dbbuild), and that the newsms program relies on other files.
  738.   
  739.   STEPS TO CREATE A DATABASE:
  740.   
  741. --- 1,8 ----
  742. ! /mit/smsdev/db/README: $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/db/RCS/README,v 1.4 90/04/25 14:54:12 mar Exp $
  743.   
  744.   This directory contains stuff necessary to create and initialize an
  745.   sms database.  Note that some other directories rely on files here
  746. ! (notably newdb), and that the newsms program relies on other files.
  747.   
  748.   STEPS TO CREATE A DATABASE:
  749.   
  750. *** /tmp/install.mss    Wed Sep  5 15:41:08 1990
  751. --- doc/install.mss    Wed Sep  5 15:40:58 1990
  752. ***************
  753. *** 145,151 ****
  754. --- 145,160 ----
  755.   and @b(register.)@i[machinename]@@@i[localrealm] is needed to run the
  756.   registration service.
  757.   
  758. + Finally, make entries in /etc/services:
  759. + @example{
  760. + sms_db        775/tcp        # Moira database
  761. + sms_update      777/tcp        # Moira update protocol
  762. + sms_ureg        779/udp        # Moira user registration
  763. + }
  764. + These are the numbers we use at Athena.  They are not officially
  765. + allocated, and you may change them at your site.
  766.   
  767.   @Subheading(Testing the Services)
  768.   
  769.   At this point the server and clients may be tested.  Run
  770. ***************
  771. *** 198,204 ****
  772. --- 207,219 ----
  773.   DCMs started every 15 minutes won't do anything until we removed that
  774.   file.
  775.   
  776. + A final piece of configuration is regular backups.  We backup the
  777. + database over the net, rather than backing up the filesystem.  This
  778. + allows us to restore the database on another machine architecture, if
  779. + necessary.  We do this by having @i(cron) run BIN_DIR@i(/nightly.sh)
  780. + at 5am each morning.
  781.   
  782.   @SubHeading(Customization)
  783.   
  784.   This is difficult to give advice on, but I'll start by describing how
  785. ***************
  786. *** 216,222 ****
  787.   objects such as users, lists, machines, etc. should be referenced by
  788.   their internal ID numbers.  If you're creating a new type that may be
  789.   referenced by other tables, assign each object a unique ID number as
  790. ! well as its name.  Add this table specification to @i(db/dbbuild), so
  791.   that recompiling the backup and restore programs will cause them to
  792.   know about the new table(s).
  793.   
  794. --- 231,237 ----
  795.   objects such as users, lists, machines, etc. should be referenced by
  796.   their internal ID numbers.  If you're creating a new type that may be
  797.   referenced by other tables, assign each object a unique ID number as
  798. ! well as its name.  Add this table specification to @i(db/newdb), so
  799.   that recompiling the backup and restore programs will cause them to
  800.   know about the new table(s).
  801.   
  802. *** /mit/bitbucket/mar/moira/doc/install.doc    Wed May  2 12:40:19 1990
  803. --- doc/install.doc    Fri Apr 20 19:35:07 1990
  804. ***************
  805. *** 91,162 ****
  806.   
  807.         Copy all of the binaries installed in bin to BIN_DIR.
  808.   
  809.   Creating the Database
  810.   
  811.   Create an Ingres database called moira with the command "createdb sms".
  812.   
  813. ! Run  the  script  db/newdb  in  quel,  the Ingres query interpreter, creating a
  814.   completely empty database.
  815.   
  816.   Run the newmoira program to initialize the database.  This program will ask:
  817.   
  818. !    1. For the name of a user to be given access to  the  database.    Root
  819. !       will  automatically  be given access; if you want someone else to be
  820. !       able to access the database through quel, then enter  their  name(s)
  821. !       here.    It  will keep asking you for names until you enter an empty
  822.         string.
  823.   
  824. !    2. The starting UID to assign.  This is the user id to be  assigned  to
  825. !       the  next  account  created.   Each time an account is created, this
  826. !       number is incremented as long as it conflicts with an  existing  UID
  827.         in the database, then the resulting value is used.
  828.   
  829.      3. The starting GID to assign.  This is used just like the UID above.
  830.   
  831. !    4. The  default  NFS  quota.    This  is  the  quota that new users are
  832.         assigned.
  833.   
  834. !    5. The name of a privileged user.  This user will be put  on  the  list
  835. !       dbadmin,  which  will be on the access control list for every query.
  836. !       This user may then  make  any  change  to  the  database,  including
  837.         putting other users on the dbadmin list.
  838.   
  839. ! At  some  point,  the  database  must  be optimized.  If a lot of data is to be
  840.   added, wait until afterwards.  Otherwise, you may do the optimization now.  The
  841. ! script  db/dbopt  contains  quel  commands to modify some of the structures and
  842. ! create additional indexes on the tables.    You  should  also  run  the  ingres
  843. ! commands  /usr/rtingres/bin/optimizedb  and /usr/rtingres/bin/sysmod after data
  844.   is loaded into the database.
  845.   
  846. ! Make sure the necessary Kerberos keys are  in  your  /etc/srvtab  file  on  the
  847. ! server.    For the initial server testing, only moira.machinename@localrealm is
  848. ! needed, but sms.[NULL]@localrealm is needed as well for updating  servers,  and
  849.   register.machinename@localrealm is needed to run the registration service.
  850.   
  851.   Testing the Services
  852.   
  853. ! At  this point the server and clients may be tested.  Run BIN_DIR/startmoira to
  854. ! get a server running.  It  will  log  everything  to  SMS_DIR/moira.log.    The
  855. ! privileged  user chosen above may run the moira client, and make changes to the
  856. ! database.  To make more privileged users, put the new users  on  the  "dbadmin"
  857.   list.
  858.   
  859. ! When  this  much  is  satisfactory, then service extraction may be initialized.
  860. ! Enable the desired services from the services sub-menu of the dcm menu  of  the
  861. ! moira  client.   Then run the DCM by invoking BIN_DIR/startdcm, and verify that
  862.   it produces the desired file.  It will log messages to SMS_DIR/dcm.log.  If the
  863.   data files are OK, then you may enable automatic update to the other servers by
  864. ! making additions in the hosts sub-menu of the dcm menu  in  the  moira  client.
  865. ! Each  host  must  be running /usr/etc/update_server and have a Kerberos key for
  866.   rcmd.hostname@localrealm in its /etc/srvtab to be able to receive updates.
  867.   
  868. ! When service updates are satisfactory,  you  can  set  up  /usr/lib/crontab  to
  869. ! invoke  BIN_DIR/startdcm  every  15  minutes.  When the DCM is started, it will
  870.   determine what work there is to do.
  871.   
  872. ! The only remaining part of the system is the registration server.  This may  be
  873. ! invoked  by  starting  BIN_DIR/startreg.    Note  that  the registration client
  874. ! (userreg) expects to find its data files in  /mit/register.    Before  you  can
  875.   successfully register new accounts, you must have
  876.   
  877.      - People entered as users in state 0
  878. --- 91,171 ----
  879.   
  880.         Copy all of the binaries installed in bin to BIN_DIR.
  881.   
  882. + Finally, make entries in /etc/services:
  883. +     sms_db          775/tcp         # Moira database
  884. +     sms_update      777/tcp         # Moira update protocol
  885. +     sms_ureg        779/udp         # Moira user registration
  886. + These are the numbers we use at Athena.  They are not officially allocated, and
  887. + you may change them at your site.
  888.   Creating the Database
  889.   
  890.   Create an Ingres database called moira with the command "createdb sms".
  891.   
  892. ! Run the script db/newdb in quel,  the  Ingres  query  interpreter,  creating  a
  893.   completely empty database.
  894.   
  895.   Run the newmoira program to initialize the database.  This program will ask:
  896.   
  897. !    1. For  the  name  of  a user to be given access to the database.  Root
  898. !       will automatically be given access; if you want someone else  to  be
  899. !       able  to  access the database through quel, then enter their name(s)
  900. !       here.  It will keep asking you for names until you  enter  an  empty
  901.         string.
  902.   
  903. !    2. The  starting  UID to assign.  This is the user id to be assigned to
  904. !       the next account created.  Each time an  account  is  created,  this
  905. !       number  is  incremented as long as it conflicts with an existing UID
  906.         in the database, then the resulting value is used.
  907.   
  908.      3. The starting GID to assign.  This is used just like the UID above.
  909.   
  910. !    4. The default NFS quota.   This  is  the  quota  that  new  users  are
  911.         assigned.
  912.   
  913. !    5. The  name  of  a privileged user.  This user will be put on the list
  914. !       dbadmin, which will be on the access control list for  every  query.
  915. !       This  user  may  then  make  any  change  to the database, including
  916.         putting other users on the dbadmin list.
  917.   
  918. ! At some point, the database must be optimized.  If a  lot  of  data  is  to  be
  919.   added, wait until afterwards.  Otherwise, you may do the optimization now.  The
  920. ! script db/dbopt contains quel commands to modify some  of  the  structures  and
  921. ! create  additional  indexes  on  the  tables.    You should also run the ingres
  922. ! commands /usr/rtingres/bin/optimizedb and /usr/rtingres/bin/sysmod  after  data
  923.   is loaded into the database.
  924.   
  925. ! Make  sure  the  necessary  Kerberos  keys  are in your /etc/srvtab file on the
  926. ! server.  For the initial server testing, only  moira.machinename@localrealm  is
  927. ! needed,  but  sms.[NULL]@localrealm is needed as well for updating servers, and
  928.   register.machinename@localrealm is needed to run the registration service.
  929.   
  930.   Testing the Services
  931.   
  932. ! At this point the server and clients may be tested.  Run BIN_DIR/startmoira  to
  933. ! get  a  server  running.    It  will  log everything to SMS_DIR/moira.log.  The
  934. ! privileged user chosen above may run the moira client, and make changes to  the
  935. ! database.    To  make more privileged users, put the new users on the "dbadmin"
  936.   list.
  937.   
  938. ! When this much is satisfactory, then service  extraction  may  be  initialized.
  939. ! Enable  the  desired services from the services sub-menu of the dcm menu of the
  940. ! moira client.  Then run the DCM by invoking BIN_DIR/startdcm, and  verify  that
  941.   it produces the desired file.  It will log messages to SMS_DIR/dcm.log.  If the
  942.   data files are OK, then you may enable automatic update to the other servers by
  943. ! making  additions  in  the  hosts sub-menu of the dcm menu in the moira client.
  944. ! Each host must be running /usr/etc/update_server and have a  Kerberos  key  for
  945.   rcmd.hostname@localrealm in its /etc/srvtab to be able to receive updates.
  946.   
  947. ! When  service  updates  are  satisfactory,  you  can set up /usr/lib/crontab to
  948. ! invoke BIN_DIR/startdcm every 15 minutes.  When the DCM  is  started,  it  will
  949.   determine what work there is to do.
  950.   
  951. ! The  only remaining part of the system is the registration server.  This may be
  952. ! invoked by starting  BIN_DIR/startreg.    Note  that  the  registration  client
  953. ! (userreg)  expects  to  find  its  data files in /mit/register.  Before you can
  954.   successfully register new accounts, you must have
  955.   
  956.      - People entered as users in state 0
  957. ***************
  958. *** 163,212 ****
  959.   
  960.      - 1 or more hosts as POP service providers listed in the hosts sub-menu
  961.        of the dcm menu in the moira client.  Value2 for each of these is the
  962. !      maximum  number  of  poboxes  that  may  be allocated on that server,
  963.        value1 is the number currently allocated.
  964.   
  965. !    - 1 or more NFS partitions listed in the nfs menu of the moira  client.
  966. !      The  declared  size  of the partition must be greater than the sum of
  967.        the quotas that will be assigned to it.  The status must be "Student"
  968.        for register to automatically assign new users there.
  969.   
  970. !    - register.moiraserver@localrealm  must  be  on  the "add" and "modify"
  971.        access control lists for the Kerberos admin server.
  972.   
  973. ! When you are confident that the system works, you may have the daemons  started
  974. ! by  /etc/rc.  We prefer to start them by hand after verifying that the database
  975. ! survived any system crash.  We also have /etc/rc create the file /etc/nodcm  at
  976.   boot time, so that the DCMs started every 15 minutes won't do anything until we
  977.   removed that file.
  978.   
  979.   Customization
  980.   
  981. ! This is difficult to give advice on, but I'll start by describing  how  we  add
  982.   new services and change things.
  983.   
  984. !    1. First  determine  what data must be recorded for this service.  What
  985.         is  the  type  of  each  datum:  integer,  string,  date,  username,
  986.         listname, machinename, other?
  987.      2. Design the Ingres table to record this information.  Integers may be
  988. !       1, 2, or 4 bytes long.   Strings  may  be  ascii  character  strings
  989. !       (storage  compresses  out  whitespace) or binary byte fields.  Other
  990. !       moira objects  such  as  users,  lists,  machines,  etc.  should  be
  991. !       referenced  by  their internal ID numbers.  If you're creating a new
  992. !       type that may be referenced by other tables, assign  each  object  a
  993. !       unique  ID number as well as its name.  Add this table specification
  994. !       to db/dbbuild, so that recompiling the backup and  restore  programs
  995.         will cause them to know about the new table(s).
  996.   
  997. !    3. If  a  new  object  type  is  added  to  the  database,  also update
  998.         server/incremental.qc to know about incremental updates to this type
  999.         of object.
  1000.   
  1001. !    4. Specify  the  queries  that  will be used to access this data.  Most
  1002. !       datatypes have 4 queries: retrieve, add, update, and delete.    Some
  1003. !       have  multiple kinds of retrieves, and/or multiple kinds of updates.
  1004. !       If you make it similar to  other  existing  queries,  you  are  more
  1005.         likely to be able to share code in the server.
  1006.   
  1007.      5. Make  the  additional  entries  in  server/queries2.c  for  the  new
  1008. --- 172,220 ----
  1009.   
  1010.      - 1 or more hosts as POP service providers listed in the hosts sub-menu
  1011.        of the dcm menu in the moira client.  Value2 for each of these is the
  1012. !      maximum number of poboxes that  may  be  allocated  on  that  server,
  1013.        value1 is the number currently allocated.
  1014.   
  1015. !    - 1  or more NFS partitions listed in the nfs menu of the moira client.
  1016. !      The declared size of the partition must be greater than  the  sum  of
  1017.        the quotas that will be assigned to it.  The status must be "Student"
  1018.        for register to automatically assign new users there.
  1019.   
  1020. !    - register.moiraserver@localrealm must be on  the  "add"  and  "modify"
  1021.        access control lists for the Kerberos admin server.
  1022.   
  1023. ! When  you are confident that the system works, you may have the daemons started
  1024. ! by /etc/rc.  We prefer to start them by hand after verifying that the  database
  1025. ! survived  any system crash.  We also have /etc/rc create the file /etc/nodcm at
  1026.   boot time, so that the DCMs started every 15 minutes won't do anything until we
  1027.   removed that file.
  1028.   
  1029.   Customization
  1030.   
  1031. ! This  is  difficult  to give advice on, but I'll start by describing how we add
  1032.   new services and change things.
  1033.   
  1034. !    1. First determine what data must be recorded for this service.    What
  1035.         is  the  type  of  each  datum:  integer,  string,  date,  username,
  1036.         listname, machinename, other?
  1037.      2. Design the Ingres table to record this information.  Integers may be
  1038. !       1,  2,  or  4  bytes  long.   Strings may be ascii character strings
  1039. !       (storage compresses out whitespace) or binary byte  fields.    Other
  1040. !       moira  objects  such  as  users,  lists,  machines,  etc.  should be
  1041. !       referenced by their internal ID numbers.  If you're creating  a  new
  1042. !       type  that  may  be referenced by other tables, assign each object a
  1043. !       unique ID number as well as its name.  Add this table  specification
  1044. !       to  db/dbbuild,  so that recompiling the backup and restore programs
  1045.         will cause them to know about the new table(s).
  1046.   
  1047. !    3. If a  new  object  type  is  added  to  the  database,  also  update
  1048.         server/incremental.qc to know about incremental updates to this type
  1049.         of object.
  1050.   
  1051. !    4. Specify the queries that will be used to access  this  data.    Most
  1052. !       datatypes  have  4 queries: retrieve, add, update, and delete.  Some
  1053. !       have multiple kinds of retrieves, and/or multiple kinds of  updates.
  1054. !       If  you  make  it  similar  to  other existing queries, you are more
  1055.         likely to be able to share code in the server.
  1056.   
  1057.      5. Make  the  additional  entries  in  server/queries2.c  for  the  new
  1058. ***************
  1059. *** 214,224 ****
  1060.         the query table is coded.  Then recompile and re-install the server.
  1061.         You can test the new queries with the mrtest client.
  1062.   
  1063. !    6. It may be necessary to write a new dcm extraction program (for  many
  1064. !       services,  this is the only thing required: no new data or queries).
  1065. !       The source to these is in the gen directory.  Note that  they  touch
  1066. !       the  database  directly, rather than going through the moira server.
  1067. !       This is for performance reasons.  These routines use the  queue  and
  1068. !       hash  table  routines  from  the  moira library.  The easiest way to
  1069. !       write a new one that does all of the time checking correctly  is  to
  1070.         start with one of the existing ones.
  1071. --- 222,232 ----
  1072.         the query table is coded.  Then recompile and re-install the server.
  1073.         You can test the new queries with the mrtest client.
  1074.   
  1075. !    6. It  may be necessary to write a new dcm extraction program (for many
  1076. !       services, this is the only thing required: no new data or  queries).
  1077. !       The  source  to these is in the gen directory.  Note that they touch
  1078. !       the database directly, rather than going through the  moira  server.
  1079. !       This  is  for performance reasons.  These routines use the queue and
  1080. !       hash table routines from the moira library.    The  easiest  way  to
  1081. !       write  a  new one that does all of the time checking correctly is to
  1082.         start with one of the existing ones.
  1083. *** /mit/bitbucket/mar/moira/doc/tech-plan/db_analysis.mss    Wed Mar 21 19:04:17 1990
  1084. --- doc/tech-plan/db_analysis.mss    Wed Apr 25 14:58:38 1990
  1085. ***************
  1086. *** 33,39 ****
  1087.   
  1088.   Two programs (@t[mrbackup] and @t[mrrestore]) are generated
  1089.   automatically (using an @t[awk] script) from the database description
  1090. ! file @t[sms/db/dbbuild]@footnote[All pathnames are relative to the
  1091.   root of the Moira source tree].  @t[mrbackup] copies each relation of
  1092.   the current Moira database into an ASCII file.  Each row of the database
  1093.   is converted into a single line of text; each line consists of several
  1094. --- 33,39 ----
  1095.   
  1096.   Two programs (@t[mrbackup] and @t[mrrestore]) are generated
  1097.   automatically (using an @t[awk] script) from the database description
  1098. ! file @t[db/newdb]@footnote[All pathnames are relative to the
  1099.   root of the Moira source tree].  @t[mrbackup] copies each relation of
  1100.   the current Moira database into an ASCII file.  Each row of the database
  1101.   is converted into a single line of text; each line consists of several
  1102. ***************
  1103. *** 60,66 ****
  1104.   @begin(programexample, Size -1) 
  1105.   # createdb smstemp
  1106.   # quel smstemp
  1107. ! * \i /u1/sms/db/dbbuild            @i(load DB definition)
  1108.   * \g                    @i(execute DB definition)
  1109.   * \q                    @i(quit)
  1110.   # mrrestore
  1111. --- 60,66 ----
  1112.   @begin(programexample, Size -1) 
  1113.   # createdb smstemp
  1114.   # quel smstemp
  1115. ! * \i /mit/moira/src/db/newdb        @i(load DB definition)
  1116.   * \g                    @i(execute DB definition)
  1117.   * \q                    @i(quit)
  1118.   # mrrestore
  1119. *** /mit/bitbucket/mar/moira/clients/moira/dcmmaint.c    Wed May  2 12:39:55 1990
  1120. --- clients/moira/dcmmaint.c    Wed Apr 25 12:42:20 1990
  1121. ***************
  1122. *** 1,4 ****
  1123. ! /* $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/dcmmaint.c,v 1.8 90/03/27 11:40:41 mar Exp $
  1124.    *
  1125.    * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
  1126.    * For copying and distribution information, please see the file
  1127. --- 1,4 ----
  1128. ! /* $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/dcmmaint.c,v 1.9 90/04/25 12:42:04 mar Exp $
  1129.    *
  1130.    * Copyright 1987, 1988 by the Massachusetts Institute of Technology.
  1131.    * For copying and distribution information, please see the file
  1132. ***************
  1133. *** 113,123 ****
  1134.   char **argv;
  1135.   {
  1136.       int status;
  1137. !     char *info[8];
  1138.   
  1139.       initserv(argv[1], info);
  1140.       askserv(info);
  1141. !     if (status = do_mr_query("add_server_info", 8, info, Scream, NULL))
  1142.         com_err(whoami, status, " while updating server info");
  1143.       FreeInfo(info);
  1144.       return(DM_NORMAL);
  1145. --- 113,123 ----
  1146.   char **argv;
  1147.   {
  1148.       int status;
  1149. !     char *info[SC_END];
  1150.   
  1151.       initserv(argv[1], info);
  1152.       askserv(info);
  1153. !     if (status = do_mr_query("add_server_info", SC_END, info, Scream, NULL))
  1154.         com_err(whoami, status, " while updating server info");
  1155.       FreeInfo(info);
  1156.       return(DM_NORMAL);
  1157. ***************
  1158. *** 178,184 ****
  1159.   int argc;
  1160.   char **argv;
  1161.   {
  1162. !     char *qargv[9];
  1163.       int status;
  1164.   
  1165.       qargv[0] = (char *)argv[1];
  1166. --- 178,184 ----
  1167.   int argc;
  1168.   char **argv;
  1169.   {
  1170. !     char *qargv[SC_END];
  1171.       int status;
  1172.   
  1173.       qargv[0] = (char *)argv[1];
  1174. ***************
  1175. *** 188,194 ****
  1176.       return(DM_NORMAL);
  1177.       }
  1178.       askserv(qargv);
  1179. !     if (status = do_mr_query("update_server_info", 8, qargv, Scream, NULL))
  1180.         com_err(whoami, status, " while updating server info");
  1181.       return(DM_NORMAL);
  1182.   }
  1183. --- 188,194 ----
  1184.       return(DM_NORMAL);
  1185.       }
  1186.       askserv(qargv);
  1187. !     if (status = do_mr_query("update_server_info", SC_END, qargv, Scream, NULL))
  1188.         com_err(whoami, status, " while updating server info");
  1189.       return(DM_NORMAL);
  1190.   }
  1191. ***************
  1192. *** 256,262 ****
  1193.   char **argv;
  1194.   {
  1195.       int status;
  1196. !     char *qargv[5], buf[BUFSIZ];
  1197.   
  1198.       sprintf(buf, "Reset state for service %s (Y/N)", argv[1]);
  1199.       if (!Confirm(buf))
  1200. --- 256,262 ----
  1201.   char **argv;
  1202.   {
  1203.       int status;
  1204. !     char *qargv[6], buf[BUFSIZ];
  1205.   
  1206.       sprintf(buf, "Reset state for service %s (Y/N)", argv[1]);
  1207.       if (!Confirm(buf))
  1208. ***************
  1209. *** 371,377 ****
  1210.   int argc;
  1211.   char **argv;
  1212.   {
  1213. !     char *info[SHI_END+1];
  1214.       int status;
  1215.   
  1216.       info[SHI_SERVICE] = strsave(argv[1]);
  1217. --- 371,377 ----
  1218.   int argc;
  1219.   char **argv;
  1220.   {
  1221. !     char *info[SHI_END];
  1222.       int status;
  1223.   
  1224.       info[SHI_SERVICE] = strsave(argv[1]);
  1225. ***************
  1226. *** 394,400 ****
  1227.   int argc;
  1228.   char **argv;
  1229.   {
  1230. !     char *info[SHI_END+1];
  1231.       int status;
  1232.   
  1233.       info[SHI_SERVICE] = strsave(argv[1]);
  1234. --- 394,400 ----
  1235.   int argc;
  1236.   char **argv;
  1237.   {
  1238. !     char *info[SHI_END];
  1239.       int status;
  1240.   
  1241.       info[SHI_SERVICE] = strsave(argv[1]);
  1242. ***************
  1243. *** 401,407 ****
  1244.       info[SHI_MACHINE] = strsave(canonicalize_hostname(argv[2]));
  1245.       inithost(info);
  1246.       askhost(info);
  1247. !     if (status = do_mr_query("add_server_host_info", 6, info, Scream, NULL))
  1248.         com_err(whoami, status, " while adding server/host info");
  1249.       FreeInfo(info);
  1250.       return(DM_NORMAL);
  1251. --- 401,408 ----
  1252.       info[SHI_MACHINE] = strsave(canonicalize_hostname(argv[2]));
  1253.       inithost(info);
  1254.       askhost(info);
  1255. !     if (status = do_mr_query("add_server_host_info", SHI_END, info,
  1256. !                  Scream, NULL))
  1257.         com_err(whoami, status, " while adding server/host info");
  1258.       FreeInfo(info);
  1259.       return(DM_NORMAL);
  1260. *** /mit/bitbucket/mar/moira/clients/moira/cluster.c    Sat Mar 17 17:10:13 1990
  1261. --- clients/moira/cluster.c    Wed Apr 25 12:35:07 1990
  1262. ***************
  1263. *** 1,5 ****
  1264.   #if (!defined(lint) && !defined(SABER))
  1265. !   static char rcsid_module_c[] = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/cluster.c,v 1.17 90/03/17 17:10:08 mar Exp $";
  1266.   #endif lint
  1267.   
  1268.   /*    This is the file cluster.c for the MOIRA Client, which allows a nieve
  1269. --- 1,5 ----
  1270.   #if (!defined(lint) && !defined(SABER))
  1271. !   static char rcsid_module_c[] = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/cluster.c,v 1.18 90/04/25 12:34:59 mar Exp $";
  1272.   #endif lint
  1273.   
  1274.   /*    This is the file cluster.c for the MOIRA Client, which allows a nieve
  1275. ***************
  1276. *** 11,17 ****
  1277.    *
  1278.    *      $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/cluster.c,v $
  1279.    *      $Author: mar $
  1280. !  *      $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/cluster.c,v 1.17 90/03/17 17:10:08 mar Exp $
  1281.    *    
  1282.    *      Copyright 1988 by the Massachusetts Institute of Technology.
  1283.    *
  1284. --- 11,17 ----
  1285.    *
  1286.    *      $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/cluster.c,v $
  1287.    *      $Author: mar $
  1288. !  *      $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/cluster.c,v 1.18 90/04/25 12:34:59 mar Exp $
  1289.    *    
  1290.    *      Copyright 1988 by the Massachusetts Institute of Technology.
  1291.    *
  1292. ***************
  1293. *** 987,993 ****
  1294.       if( (stat = do_mr_query("add_cluster_data", 3, argv + 1,
  1295.                    Scream, (char *) NULL)) != 0)
  1296.       com_err(program_name, stat, " in AddClusterData.");
  1297.   }
  1298.   
  1299.   /*    Function Name: RealRemoveClusterData
  1300. --- 987,993 ----
  1301.       if( (stat = do_mr_query("add_cluster_data", 3, argv + 1,
  1302.                    Scream, (char *) NULL)) != 0)
  1303.       com_err(program_name, stat, " in AddClusterData.");
  1304. !     return(DM_NORMAL);
  1305.   }
  1306.   
  1307.   /*    Function Name: RealRemoveClusterData
  1308. *** /mit/bitbucket/mar/moira/clients/moira/delete.c    Sat Mar 17 17:10:29 1990
  1309. --- clients/moira/delete.c    Wed Apr 25 12:50:47 1990
  1310. ***************
  1311. *** 1,5 ****
  1312.   #if (!defined(lint) && !defined(SABER))
  1313. !   static char rcsid_module_c[] = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/delete.c,v 1.16 90/03/17 17:10:23 mar Exp $";
  1314.   #endif lint
  1315.   
  1316.   /*    This is the file delete.c for the MOIRA Client, which allows a nieve
  1317. --- 1,5 ----
  1318.   #if (!defined(lint) && !defined(SABER))
  1319. !   static char rcsid_module_c[] = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/delete.c,v 1.17 90/04/25 12:50:26 mar Exp $";
  1320.   #endif lint
  1321.   
  1322.   /*    This is the file delete.c for the MOIRA Client, which allows a nieve
  1323. ***************
  1324. *** 11,17 ****
  1325.    *
  1326.    *      $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/delete.c,v $
  1327.    *      $Author: mar $
  1328. !  *      $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/delete.c,v 1.16 90/03/17 17:10:23 mar Exp $
  1329.    *    
  1330.    *      Copyright 1988 by the Massachusetts Institute of Technology.
  1331.    *
  1332. --- 11,17 ----
  1333.    *
  1334.    *      $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/delete.c,v $
  1335.    *      $Author: mar $
  1336. !  *      $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/delete.c,v 1.17 90/04/25 12:50:26 mar Exp $
  1337.    *    
  1338.    *      Copyright 1988 by the Massachusetts Institute of Technology.
  1339.    *
  1340. ***************
  1341. *** 426,431 ****
  1342. --- 426,432 ----
  1343.       return(SUB_NORMAL);
  1344.   }
  1345.   
  1346. + #ifndef ATHENA
  1347.   /*    Function Name: RealDeleteUser
  1348.    *    Description: Just Deletes the user.
  1349.    *    Arguments: name - name of User to delete
  1350. ***************
  1351. *** 448,453 ****
  1352. --- 449,455 ----
  1353.       Put_message(buf);
  1354.       return(SUB_NORMAL);
  1355.   }
  1356. + #endif
  1357.   
  1358.   /*    Function Name: RealDeleteList
  1359.    *    Description: Just Deletes the list.
  1360. ***************
  1361. *** 636,642 ****
  1362. --- 638,646 ----
  1363.       int status;
  1364.       char buf[BUFSIZ];
  1365.       char * name = argv[1];    /* name of the user we are deleting. */
  1366. + #ifndef ATHENA
  1367.       struct qelem *local, *member_of = NULL;
  1368. + #endif
  1369.   
  1370.       if (!ValidName(name))
  1371.       return(DM_NORMAL);
  1372. ***************
  1373. *** 652,665 ****
  1374.       if (status == 0) {
  1375.       sprintf(buf,"User %s deleted.", name);
  1376.       Put_message(buf);
  1377.       /* delete this return if the policy decision below is reversed */
  1378.       return(DM_NORMAL);
  1379.       }
  1380.   /* Design decision not to allow registered users to be deleted.
  1381.    */
  1382.       Put_message("Sorry, registered users cannot be deleted from the database.");
  1383.       Put_message("Deactivate the user now, and the system manager will expunge later.");
  1384. ! #ifdef notdef
  1385.       else if (status == MR_IN_USE) {
  1386.   
  1387.   /*
  1388. --- 656,672 ----
  1389.       if (status == 0) {
  1390.       sprintf(buf,"User %s deleted.", name);
  1391.       Put_message(buf);
  1392. + #ifdef ATHENA
  1393.       /* delete this return if the policy decision below is reversed */
  1394.       return(DM_NORMAL);
  1395. + #endif
  1396.       }
  1397. + #ifdef ATHENA
  1398.   /* Design decision not to allow registered users to be deleted.
  1399.    */
  1400.       Put_message("Sorry, registered users cannot be deleted from the database.");
  1401.       Put_message("Deactivate the user now, and the system manager will expunge later.");
  1402. ! #else
  1403.       else if (status == MR_IN_USE) {
  1404.   
  1405.   /*
  1406. *** /mit/bitbucket/mar/moira/clients/moira/pobox.c    Sat Mar 17 17:11:11 1990
  1407. --- clients/moira/pobox.c    Wed Apr 25 12:39:55 1990
  1408. ***************
  1409. *** 1,5 ****
  1410.   #if (!defined(lint) && !defined(SABER))
  1411. !   static char rcsid_module_c[] = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/pobox.c,v 1.14 90/03/17 17:11:09 mar Exp $";
  1412.   #endif lint
  1413.   
  1414.   /*    This is the file pobox.c for the MOIRA Client, which allows a nieve
  1415. --- 1,5 ----
  1416.   #if (!defined(lint) && !defined(SABER))
  1417. !   static char rcsid_module_c[] = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/pobox.c,v 1.15 90/04/25 12:39:49 mar Exp $";
  1418.   #endif lint
  1419.   
  1420.   /*    This is the file pobox.c for the MOIRA Client, which allows a nieve
  1421. ***************
  1422. *** 11,17 ****
  1423.    *
  1424.    *      $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/pobox.c,v $
  1425.    *      $Author: mar $
  1426. !  *      $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/pobox.c,v 1.14 90/03/17 17:11:09 mar Exp $
  1427.    *    
  1428.    *      Copyright 1988 by the Massachusetts Institute of Technology.
  1429.    *
  1430. --- 11,17 ----
  1431.    *
  1432.    *      $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/pobox.c,v $
  1433.    *      $Author: mar $
  1434. !  *      $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/pobox.c,v 1.15 90/04/25 12:39:49 mar Exp $
  1435.    *    
  1436.    *      Copyright 1988 by the Massachusetts Institute of Technology.
  1437.    *
  1438. ***************
  1439. *** 225,230 ****
  1440. --- 225,231 ----
  1441.       }
  1442.       
  1443.       default:            /* ^C hit. */
  1444. +     type = "NONE";
  1445.       break;
  1446.       }
  1447.   
  1448. *** /mit/bitbucket/mar/moira/clients/moira/utils.c    Wed May  2 12:40:12 1990
  1449. --- clients/moira/utils.c    Wed May  2 13:13:43 1990
  1450. ***************
  1451. *** 1,5 ****
  1452.   #if (!defined(lint) && !defined(SABER))
  1453. !   static char rcsid_module_c[] = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/utils.c,v 1.25 90/04/09 18:05:03 mar Exp $";
  1454.   #endif lint
  1455.   
  1456.   /*    This is the file utils.c for the MOIRA Client, which allows a nieve
  1457. --- 1,5 ----
  1458.   #if (!defined(lint) && !defined(SABER))
  1459. !   static char rcsid_module_c[] = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/utils.c,v 1.26 90/05/02 13:13:32 mar Exp $";
  1460.   #endif lint
  1461.   
  1462.   /*    This is the file utils.c for the MOIRA Client, which allows a nieve
  1463. ***************
  1464. *** 11,17 ****
  1465.    *
  1466.    *      $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/utils.c,v $
  1467.    *      $Author: mar $
  1468. !  *      $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/utils.c,v 1.25 90/04/09 18:05:03 mar Exp $
  1469.    *    
  1470.    *      Copyright 1988 by the Massachusetts Institute of Technology.
  1471.    *
  1472. --- 11,17 ----
  1473.    *
  1474.    *      $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/utils.c,v $
  1475.    *      $Author: mar $
  1476. !  *      $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/clients/moira/RCS/utils.c,v 1.26 90/05/02 13:13:32 mar Exp $
  1477.    *    
  1478.    *      Copyright 1988 by the Massachusetts Institute of Technology.
  1479.    *
  1480. ***************
  1481. *** 858,864 ****
  1482.       return(GetTypeFromUser(prompt, tname, pointer));
  1483.       }
  1484.       for (elem = GetTypeValues(tname); elem; elem = elem->q_forw) {
  1485. !     if (!cistrcmp(elem->q_data, *pointer)) {
  1486.           strcpy(*pointer, elem->q_data);
  1487.           return(SUB_NORMAL);
  1488.       }
  1489. --- 864,870 ----
  1490.       return(GetTypeFromUser(prompt, tname, pointer));
  1491.       }
  1492.       for (elem = GetTypeValues(tname); elem; elem = elem->q_forw) {
  1493. !     if (!strcasecmp(elem->q_data, *pointer)) {
  1494.           strcpy(*pointer, elem->q_data);
  1495.           return(SUB_NORMAL);
  1496.       }
  1497. *** /mit/bitbucket/mar/moira/rpc/strs.c    Tue Sep 13 15:53:49 1988
  1498. --- rpc/strs.c    Wed May  2 13:12:19 1990
  1499. ***************
  1500. *** 1,7 ****
  1501.   /*
  1502. !  *    $Source: /mit/smsdev/rpc/RCS/strs.c,v $
  1503.    *    $Author: mar $
  1504. !  *    $Header: strs.c,v 1.5 88/09/13 15:52:49 mar Exp $
  1505.    *
  1506.    *    Copyright (C) 1987 by the Massachusetts Institute of Technology
  1507.    *    For copying and distribution information, please see the file
  1508. --- 1,7 ----
  1509.   /*
  1510. !  *    $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/strs.c,v $
  1511.    *    $Author: mar $
  1512. !  *    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/strs.c,v 1.6 90/05/02 13:12:11 mar Exp $
  1513.    *
  1514.    *    Copyright (C) 1987 by the Massachusetts Institute of Technology
  1515.    *    For copying and distribution information, please see the file
  1516. ***************
  1517. *** 11,17 ****
  1518.    */
  1519.   
  1520.   #ifndef lint
  1521. ! static char *rcsid_strs_c = "$Header: strs.c,v 1.5 88/09/13 15:52:49 mar Exp $";
  1522.   #endif lint
  1523.   
  1524.   #include <mit-copyright.h>
  1525. --- 11,17 ----
  1526.    */
  1527.   
  1528.   #ifndef lint
  1529. ! static char *rcsid_strs_c = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/strs.c,v 1.6 90/05/02 13:12:11 mar Exp $";
  1530.   #endif lint
  1531.   
  1532.   #include <mit-copyright.h>
  1533. ***************
  1534. *** 73,93 ****
  1535.       *t = '\0';
  1536.       return s;
  1537.   }
  1538. - /*
  1539. -  * Case insensitive string compare.
  1540. -  */
  1541. - int cistrcmp(cp1, cp2)
  1542. -     char *cp1, *cp2;
  1543. - {
  1544. -     register int c1, c2;
  1545. -     
  1546. -     do {
  1547. -     if (isupper(c1 = (*cp1++))) c1 = tolower(c1);
  1548. -     if (isupper(c2 = (*cp2++))) c2 = tolower(c2);
  1549. -     if (c1 != c2) return c1-c2;
  1550. -     } while (c1 && c2);
  1551. -     return 0;
  1552. - }
  1553. --- 73,75 ----
  1554. *** /mit/bitbucket/mar/moira/rpc/nfsparttype.c    Sat Mar 17 16:37:15 1990
  1555. --- rpc/nfsparttype.c    Wed May  2 13:12:30 1990
  1556. ***************
  1557. *** 1,7 ****
  1558.   /*
  1559.    *    $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/nfsparttype.c,v $
  1560.    *    $Author: mar $
  1561. !  *    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/nfsparttype.c,v 1.3 90/03/17 16:37:13 mar Exp $
  1562.    *
  1563.    *    Copyright (C) 1987 by the Massachusetts Institute of Technology
  1564.    *    For copying and distribution information, please see the file
  1565. --- 1,7 ----
  1566.   /*
  1567.    *    $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/nfsparttype.c,v $
  1568.    *    $Author: mar $
  1569. !  *    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/nfsparttype.c,v 1.4 90/05/02 13:12:20 mar Exp $
  1570.    *
  1571.    *    Copyright (C) 1987 by the Massachusetts Institute of Technology
  1572.    *    For copying and distribution information, please see the file
  1573. ***************
  1574. *** 10,16 ****
  1575.    */
  1576.   
  1577.   #ifndef lint
  1578. ! static char *rcsid_nfsparttype_c = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/nfsparttype.c,v 1.3 90/03/17 16:37:13 mar Exp $";
  1579.   #endif lint
  1580.   
  1581.   #include <mit-copyright.h>
  1582. --- 10,16 ----
  1583.    */
  1584.   
  1585.   #ifndef lint
  1586. ! static char *rcsid_nfsparttype_c = "$Header: /afs/athena.mit.edu/astaff/project/moiradev/src/rpc/RCS/nfsparttype.c,v 1.4 90/05/02 13:12:20 mar Exp $";
  1587.   #endif lint
  1588.   
  1589.   #include <mit-copyright.h>
  1590. ***************
  1591. *** 105,111 ****
  1592.       t = strtrim(temp);    /* nuke leading and trailing whitespace */
  1593.   
  1594.       for (pp = fs_names; pp->type; pp++) {
  1595. !         if (cistrcmp(pp->name, t) == 0) {
  1596.           flags |= pp->type;
  1597.           break;
  1598.           }
  1599. --- 104,110 ----
  1600.       t = strtrim(temp);    /* nuke leading and trailing whitespace */
  1601.   
  1602.       for (pp = fs_names; pp->type; pp++) {
  1603. !         if (strcasecmp(pp->name, t) == 0) {
  1604.           flags |= pp->type;
  1605.           break;
  1606.           }
  1607. *** /mit/bitbucket/mar/moira/update/Makefile    Mon Mar 19 13:04:26 1990
  1608. --- update/Makefile    Wed May  2 13:20:36 1990
  1609. ***************
  1610. *** 1,6 ****
  1611.   #
  1612.   #     $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/update/RCS/Makefile,v $
  1613. ! #    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/update/RCS/Makefile,v 1.16 90/03/19 13:04:21 mar Exp $
  1614.   #
  1615.   
  1616.   #
  1617. --- 1,6 ----
  1618.   #
  1619.   #     $Source: /afs/athena.mit.edu/astaff/project/moiradev/src/update/RCS/Makefile,v $
  1620. ! #    $Header: /afs/athena.mit.edu/astaff/project/moiradev/src/update/RCS/Makefile,v 1.17 90/05/02 13:20:25 mar Exp $
  1621.   #
  1622.   
  1623.   #
  1624. ***************
  1625. *** 31,37 ****
  1626.   
  1627.   LIBS=    -L../lib -lmoira -lgdb -lkrb -ldes -lcom_err
  1628.   
  1629. ! all:    moira_update.o update_server sms_untar
  1630.   
  1631.   update_server: ${SOBJS}
  1632.       cc ${CFLAGS} -o update_server ${SOBJS} ${LIBS}
  1633. --- 31,37 ----
  1634.   
  1635.   LIBS=    -L../lib -lmoira -lgdb -lkrb -ldes -lcom_err
  1636.   
  1637. ! all:    moira_update.o update_server
  1638.   
  1639.   update_server: ${SOBJS}
  1640.       cc ${CFLAGS} -o update_server ${SOBJS} ${LIBS}
  1641. ***************
  1642. *** 39,57 ****
  1643.   moira_update.o: ${COBJS}
  1644.       ld -r -o moira_update.o ${COBJS}
  1645.   
  1646. - sms_untar: sms_untar.c
  1647. -     cc -o sms_untar ${INCS} sms_untar.c
  1648.   
  1649.   clean:    
  1650.       -rm -f ${COBJS} ${SOBJS}
  1651.       -rm -f update_server moira_update.o
  1652. -     -rm -f sms_untar
  1653.       -rm -f core a.out *~ \#*
  1654.   
  1655.   install: update_server
  1656.       install -c -s update_server ${DESTDIR}/usr/etc/update_server
  1657. -     install -c -s sms_untar ${DESTDIR}/etc/sms_untar
  1658.   
  1659.   lint:
  1660.       lint ${LINTFLAGS} ${SSRCS}
  1661. --- 39,52 ----
  1662.